<?php

namespace app\common\service\shop;

use app\common\bin\lazada\lazop\LazopClient;
use app\common\bin\lazada\lazop\LazopRequest;
use Exception;
use think\exception\ValidateException;

/**
 * LazadaService
 * @Description Lazada接口服务
 * @author shirukun
 * @date 2024-10-18
 */
class Lazada
{

    // AccessToken RefreshAccessToken 接口地址
    private $token_url = 'https://auth.lazada.com/rest';

    // api接口地址
    private $api_url = [
        'Vietnam' => 'https://api.lazada.vn/rest', // 越南
        'Singapore' => 'https://api.lazada.sg/rest', // 新加坡
        'Philippines' => 'https://api.lazada.com.ph/rest', // 菲律宾
        'Malaysia' => 'https://api.lazada.com.my/rest', // 马来西亚
        'Thailand' => 'https://api.lazada.co.th/rest', // 泰国
        'Indonesia' => 'https://api.lazada.co.id/rest', // 印尼
    ];

    // 配置
    protected $config = [
        'app_key' => '128499',
        'app_secret' => 'cLN1n8LQZI5lJGUQsXqsY7Tb4O3Gsaik',
        'code' => '0_128499_ZXNWAK1GJ2nCaxoVTOFCJxfs35646',
        'access_token' => '5000050002628PcwURdFTSiwgInR1Mxfa4nvhk149bc49fSbuwEdkAyhk5P4RZ0n',
        'refresh_token' => '50001501326s822gvGlUDzti6CET9KzzellLly1bc9a682GsvHE3HOxEJ2RHXic2',
        'site' => 'Singapore',
    ];

    /**
     * 错误信息
     */
    public $err;

    /**
     * 获取错误信息
     * @return array
     */
    public function getErr()
    {
        return $this->err;
    }

    /**
     * 构造方法 设置参数
     * @param array $config 配置参数
     * @throws Exception
     */
    public function __construct($config = [])
    {

        $this->config = array_merge($this->config, $config);
        try {
            validate([
                'app_key' => 'require',
                'app_secret' => 'require',
                'code' => 'require',
                'site' => 'require',

            ], [
                'app_key.require' => 'lazada配置App Key不存在',
                'app_secret.require' => 'lazada配置应用秘钥不存在',
                'code.require' => 'lazada配置code不存在',
                'site.require' => 'lazada配置site不存在',
            ])->check($this->config);
        } catch (ValidateException $e) {
            // 验证失败 输出错误信息
//            Log::record($e->getMessage(), 'export');
            throw new Exception($e->getMessage());
        }
        if (empty($this->config['access_token'])) $this->getAccessToken();
    }

    /**
     * Desc: 获取AccessToken
     * @return string
     */
    public function getAccessToken()
    {
        //返回示例
        //{"access_token":"50000301528bX9xdjQasslYciRdPsyDijvnaetUj1ba52b72CwBPtgLo2X3okrlv","country":"cb","refresh_token":"50001300b28gPalApWnqdh0g1EHUawPfcDhU4nTT1562c9e6Cfgul1fqzruyxkVh","account_platform":"seller_center","refresh_expires_in":15552000,"country_user_info":[{"country":"sg","user_id":"1280192025","seller_id":"1280192025","short_code":"SGOE3OP0"},{"country":"th","user_id":"100635344354","seller_id":"100635344354","short_code":"TH1JR3A1HZ"},{"country":"vn","user_id":"200588704381","seller_id":"200588704381","short_code":"VN34463R4G"},{"country":"ph","user_id":"500763328609","seller_id":"500763328609","short_code":"PH7SEE65OJ"},{"country":"id","user_id":"401805984157","seller_id":"401805984157","short_code":"ID68KA350X"},{"country":"my","user_id":"300389360347","seller_id":"300389360347","short_code":"MY4NEC5UCS"}],"expires_in":2592000,"account":"abnerali@aliyun.com","code":"0","request_id":"2101069617110867691263367"}
        $c = new LazopClient($this->token_url, $this->config['app_key'], $this->config['app_secret']);
        $request = new LazopRequest('/auth/token/create');
        $request->addApiParam('code', $this->config['code']);
        halt($c->execute($request));
        $res = json_decode($c->execute($request), true);
//        Log::record($res, 'export');
        if ($res['code'] == "0") {

            // todo 储存配置信息

            $this->config['access_token'] = $res['access_token'];
            $this->config['refresh_token'] = $res['refresh_token'];
        } else {
            throw new Exception($res['message']);
        }
    }


    /**
     * Desc: 获取refreshAccessToken
     * @return string
     */
    public function refreshAccessToken()
    {
        $c = new LazopClient($this->token_url, $this->config['app_key'], $this->config['app_secret']);
        $request = new LazopRequest('/auth/token/refresh');
        $request->addApiParam('refresh_token', $this->config['refresh_token']);
        $res = json_decode($c->execute($request), true);
//        Log::record($res, 'export');
        if ($res['code'] == "0") {

            // todo 储存配置信息

            $this->config['access_token'] = $res['access_token'];
            $this->config['refresh_token'] = $res['refresh_token'];
        } else {
            throw new Exception($res['message']);
        }
    }
    /**
     * Desc: 获取订单组装数据
     * @param $where
     * @return mixed
     */
    public function syncOrder($where = []): mixed
    {
//        Log::record($where, 'test');
        $params = [
            'offset' => '0',
            'limit' => '100',
            'created_after' => date('c'),
            'created_before' => date('c'),
        ];
        $params['created_after'] = date('c', strtotime(date('Y/m/d 00:00:00')));
        $params['created_before'] = date('c', strtotime(date('Y/m/d 23:59:59')));
//        halt($params);

        $pretreatment_order = [];

        $res = $this->getOrdes($this->api_url[$this->config['site']], $params);
        $res = json_decode($res, true);
        halt($res);

        if ($res['code'] == "0") {

            // 订单列表
            $orderData = $res['data']['orders'];
//                Log::record($orderData, 'export');
//                if (!empty($orderData)) {
//
//                    // 订单ids
//                    $orderIds = array_column($orderData, 'order_id');
//
//                    foreach ($orderIds as $orderId) {
//
//                        // 订单详情
//                        $orderItemsData = $this->getOrderItems($this->api_url[$this->config['site']], $orderId);
//                        $orderItemsData = array_column($orderItemsData, null, 'order_id');
////                        Log::record($orderItemsData, 'export');
//
//                    }
//                }
        }
        return $pretreatment_order;
    }

    /**
     * Desc: 获取订单
     * @param $url
     * @param $params
     * @return string
     */
    public function getOrdes($url, $params)
    {
//        $c = new LazopClient($this->api_url['Vietnam'], $this->config['app_key'], $this->config['app_secret']);
        $c = new LazopClient($url, $this->config['app_key'], $this->config['app_secret']);
        $request = new LazopRequest('/orders/get', 'GET');
//        $request->addApiParam('update_before','2018-02-10T16:00:00+08:00');
        $request->addApiParam('sort_direction', 'DESC');
        $request->addApiParam('offset', $params['offset']);
        $request->addApiParam('limit', $params['limit']);
//        $request->addApiParam('update_after','2017-02-10T09:00:00+08:00');
        $request->addApiParam('sort_by', 'created_at');
        $request->addApiParam('created_before', $params['created_before']);
        $request->addApiParam('created_after', $params['created_after']);
//        $request->addApiParam('status', 'topack');
        return $c->execute($request, $this->config['access_token']);
    }


    /**
     * Desc: 获取订单详情 GetMultipleOrderItems
     * @param $url
     * @param $orderId
     * @return mixed
     */
    public function getOrderItems($url, $orderId)
    {
        $c = new LazopClient($url, $this->config['app_key'], $this->config['app_secret']);
        $request = new LazopRequest('/orders/items/get', 'GET');
        $request->addApiParam('order_ids', '[' . $orderId . ']');
        $res = $c->execute($request, $this->config['access_token']);
//        Log::record($res, 'export');
        $res = json_decode($res, true);
        if ($res['code'] == "0") {
            return $res['data'];
        } else {
            throw new Exception($res['message']);
        }
    }


    /**
     * Desc: 创建商品组装数据
     * @return mixed
     */
    public function syncCreateProduct(): mixed
    {
        $params = [
            'Request' => [
                "Product" => [
                    "PrimaryCategory" => "3", // 可选 类别id todo
                    "AssociatedSku" => "Existing SkuId in seller center", // 可选 当将一些 SKU 添加到现有产品时，需要使用此标签 //用于将SKU与现有产品关联。如果在卖家中心正常显示，必须填写。 //卖家中心中的现有 SkuId
                    "Images" => [ // 可选	产品的图片数组，最多支持8张图片。SKU属性中的图片表示变体图片，外部图片表示SPU图片。
                        "Image" => [
                            "https://my-live-02.slatic.net/p/47b6cb07bd8f80aa3cc34b180b902f3e.jpg",
                        ]
                    ],
                    "Attributes" => [
    //                    "propCascade" => [
    //                        "26" => "120013644:162,100006867:160387",
    //                    ],
                        "name" => "test-2024-10-".time(), // 产品名称，最多255个字符。
                        "disableAttributeAutoFill" => false, // 可选	设置为true以禁用产品规格属性的自动填充。默认值为false。
                        "description" => "TEST", // 可选	最多25000个字符；支持HTML标签。仅接受Lazada的图片URL。
//                        "brand" => "No Brand", // “品牌”将被弃用，请使用“品牌_id”
                        "brand_id" => "23902", // 从GetBrandByPages API中获取的值。 todo
    //                    "video" => "", // 可选	上传后，从GetVideo或CompleteCreateVideo响应中填写视频ID。状态必须为AUDIT_SUCCESS。
    //                    "model" => "test",
    //                    "waterproof" => "Waterproof",
                        "warranty_type" => "Local seller warranty", // 当地经销商保修
    //                    "warranty" => "1 Month",
                        "short_description" => "cm x 1efgtecm<br /><brfwefgtek",// 可选	仅文本；可以使用 <ul> <li> 或 <ol> <li> 标签。短描述会自动过滤掉图片和URL。
    //                    "Hazmat" => "None",
    //                    "material" => "Leather",
    //                    "laptop_size" => "11 - 12 inches",
    //                    "delivery_option_sof" => "Yes",
                        "gift_wrapping" => "Yes", // 可选	包装功能。更多信息请联系PSC。可选值：Yes/Yes。
                        "name_engravement" => "Yes", // 可选	雕刻功能。更多信息请联系PSC。可选值：Yes/Yes。
                        "preorder_enable" => "Yes", // 可选	预售开关，启用/禁用产品。可选值：Yes/Yes。
                        "preorder_days" => "25", // 可选	预售启用时，输入预计的处理天数。范围因卖家而异；如需更改，请咨询Lazada运营人员。
                    ],
                    "Skus" => [
                        "Sku" => [
                            [
                                "SellerSku" => "test2024-10-".time(), // 卖家可自定义；在同一商品中必须唯一。
                                "saleProp" => [ // 可选	根据SKU区分销售属性。
                                    "color_family" => "Green", // 可选	创建多个SKU时必填；标准变体属性，可能因类别而异（例如，大小）。
                                    "size" => "10", //  // 可选	创建多个SKU时必填；标准变体属性，可能因类别而异（例如，大小）。
                                ],
                                "quantity" => "3",
                                "price" => "35", // 必填	产品的零售价格；如果未填写“special_price”或已过期，则显示此价格。
                                "special_price" => "33", // 可选	产品的实际销售价格。如果填写了“special_from_date”和“special_to_date”，则此字段为必填。
                                "special_from_date" => "2024-10-20 17:18:31", // 可选	特殊价格的开始时间；如果填写此字段，则“special_price”字段为必填。
                                "special_to_date" => "2025-10-15 17:18:31", // 可选	特殊价格的结束时间；如果填写此字段，则“special_price”字段为必填。
                                "package_height" => "10", // 最多保留两位小数，单位：cm。
                                "package_length" => "10", // 最多保留两位小数，单位：cm。
                                "package_width" => "10", // 最多保留两位小数，单位：cm。
                                "package_weight" => "0.5", // 最多保留两位小数，单位：kg。
                                "package_content" => "laptop bag", // 可选	关于包装的详细信息。
                                "Images" => [ // // 可选	产品的图片数组，最多支持8张图片。SKU属性中的图片表示变体图片，外部图片表示SPU图片。
                                    "Image" => [
                                        "https://my-live-02.slatic.net/p/47b6cb07bd8f80aa3cc34b180b902f3e.jpg",
                                    ]
                                ]
                            ],
                        ]
                    ]
                ]
            ]
        ];
        $params = json_encode($params,320);

        $res = $this->createProduct($this->api_url[$this->config['site']], $params);
        $res = json_decode($res, true);
        halt($res);
    }

    /**
     * Desc: 创建商品
     * @param $url
     * @param $params
     * @return bool|string
     */
    public function createProduct($url, $params)
    {
//        halt($params);

//        $c = new LazopClient($this->api_url['Vietnam'], $this->config['app_key'], $this->config['app_secret']);
        $c = new LazopClient($url, $this->config['app_key'], $this->config['app_secret']);
        $request = new LazopRequest('/product/create', 'POST');
        $request->addApiParam('payload', $params);
        return $c->execute($request, $this->config['access_token']);
    }


    /**
     * Desc: 更新商品组装数据
     * @return mixed
     */
    public function syncUpdateProduct(): mixed
    {
        $params = [
            'Request' => [
                "Product" => [
                    "PrimaryCategory" => "10002019", // 可选 类别id todo
                    "AssociatedSku" => "Existing SkuId in seller center", // 可选 当将一些 SKU 添加到现有产品时，需要使用此标签 //用于将SKU与现有产品关联。如果在卖家中心正常显示，必须填写。 //卖家中心中的现有 SkuId
                    "Images" => [ // 可选	产品的图片数组，最多支持8张图片。SKU属性中的图片表示变体图片，外部图片表示SPU图片。
                        "Image" => [
                            "https://my-live-02.slatic.net/p/47b6cb07bd8f80aa3cc34b180b902f3e.jpg",
                        ]
                    ],
                    "Attributes" => [
    //                    "propCascade" => [
    //                        "26" => "120013644:162,100006867:160387",
    //                    ],
                        "name" => "test-2024-10-".time(), // 产品名称，最多255个字符。
                        "disableAttributeAutoFill" => false, // 可选	设置为true以禁用产品规格属性的自动填充。默认值为false。
                        "description" => "TEST", // 可选	最多25000个字符；支持HTML标签。仅接受Lazada的图片URL。
                        "brand" => "No Brand", // “品牌”将被弃用，请使用“品牌_id”
                        "brand_id" => "30768", // 从GetBrandByPages API中获取的值。 todo
    //                    "video" => "", // 可选	上传后，从GetVideo或CompleteCreateVideo响应中填写视频ID。状态必须为AUDIT_SUCCESS。
    //                    "model" => "test",

//                        "d_description" => "Yes", // 可选 删除详细描述
//                        "d_short_description" => "Yes", // 可选 删除现有马来语版本的详细描述。
//                        "d_short_description_en" => "Yes", // 可选 删除已经存在的英文版的长描述。
//                        "remove_video" => "Yes", // 可选 “Yes”以删除产品视频

    //                    "waterproof" => "Waterproof",
                        "warranty_type" => "Local seller warranty", // 当地经销商保修
    //                    "warranty" => "1 Month",
                        "short_description" => "cm x 1efgtecm<br /><brfwefgtek",// 可选	仅文本；可以使用 <ul> <li> 或 <ol> <li> 标签。短描述会自动过滤掉图片和URL。
    //                    "Hazmat" => "None",
    //                    "material" => "Leather",
    //                    "laptop_size" => "11 - 12 inches",
    //                    "delivery_option_sof" => "Yes",
                        "gift_wrapping" => "Yes", // 可选	包装功能。更多信息请联系PSC。可选值：Yes/Yes。
                        "name_engravement" => "Yes", // 可选	雕刻功能。更多信息请联系PSC。可选值：Yes/Yes。
                        "preorder_enable" => "Yes", // 可选	预售开关，启用/禁用产品。可选值：Yes/Yes。
                        "preorder_days" => "25", // 可选	预售启用时，输入预计的处理天数。范围因卖家而异；如需更改，请咨询Lazada运营人员。
                    ],
                    "Skus" => [
                        "Sku" => [
                            [
                                "SkuId" => "test2024-10-".time(), // Sku id由Lazada在产品创建时创建，用于在产品更新时定位需要更新的Sku或产品。
                                "saleProp" => [ // 可选	根据SKU区分销售属性。
                                    "color_family" => "Green", // 可选	创建多个SKU时必填；标准变体属性，可能因类别而异（例如，大小）。
                                    "size" => "10", //  // 可选	创建多个SKU时必填；标准变体属性，可能因类别而异（例如，大小）。
                                ],
                                "quantity" => "3",
                                "price" => "35", // 必填	产品的零售价格；如果未填写“special_price”或已过期，则显示此价格。
                                "special_price" => "33", // 可选	产品的实际销售价格。如果填写了“special_from_date”和“special_to_date”，则此字段为必填。
                                "special_from_date" => "2024-10-20 17:18:31", // 可选	特殊价格的开始时间；如果填写此字段，则“special_price”字段为必填。
                                "special_to_date" => "2025-10-15 17:18:31", // 可选	特殊价格的结束时间；如果填写此字段，则“special_price”字段为必填。
                                "package_height" => "10", // 最多保留两位小数，单位：cm。
                                "package_length" => "10", // 最多保留两位小数，单位：cm。
                                "package_width" => "10", // 最多保留两位小数，单位：cm。
                                "package_weight" => "0.5", // 最多保留两位小数，单位：kg。
                                "package_content" => "laptop bag", // 可选	关于包装的详细信息。
//                                "Status" => "active", // 可选 下列值之一:active“活动”、inactive“非活动”或deleted“已删除”。可选。默认值为active“活动”
                                "Images" => [ // // 可选	产品的图片数组，最多支持8张图片。SKU属性中的图片表示变体图片，外部图片表示SPU图片。
                                    "Image" => [
                                        "https://my-live-02.slatic.net/p/47b6cb07bd8f80aa3cc34b180b902f3e.jpg",
                                    ]
                                ]
                            ],
                        ]
                    ]
                ]
            ]
        ];
        $params = json_encode($params,320);

        $res = $this->updateProduct($this->api_url[$this->config['site']], $params);
        $res = json_decode($res, true);
        halt($res);
    }

    /**
     * Desc: 更新商品
     * @param $url
     * @param $params
     * @return bool|string
     */
    public function updateProduct($url, $params)
    {
//        $c = new LazopClient($this->api_url['Vietnam'], $this->config['app_key'], $this->config['app_secret']);
        $c = new LazopClient($url, $this->config['app_key'], $this->config['app_secret']);
        $request = new LazopRequest('/product/update');
        $request->addApiParam('payload', $params);
        return $c->execute($request, $this->config['access_token']);
    }

    /**
     * Desc: 获取商品品牌列表
     * @param $params
     * @return bool|string
     */
    public function getBrandByPages($startRow = 1,$pageSize = 200)
    {
//        halt($params);

        $c = new LazopClient($this->api_url[$this->config['site']], $this->config['app_key'], $this->config['app_secret']);
        $request = new LazopRequest('/category/brands/query', 'POST');
        $request->addApiParam('startRow',$startRow);
        $request->addApiParam('pageSize',$pageSize);
        $res = $c->execute($request);
        $res = json_decode($res, true);
        halt($res);
    }

    /**
     * Desc: 获取商品类别树
     * @param $params
     * @return bool|string
     */
    public function GetCategoryTree($language_code = 'en_US')
    {
//        halt($params);

        $c = new LazopClient($this->api_url[$this->config['site']], $this->config['app_key'], $this->config['app_secret']);
        $request = new LazopRequest('/category/tree/get','GET');
        $request->addApiParam('language_code',$language_code);
        $res = $c->execute($request);
        $res = json_decode($res, true);
        halt($res);
    }
}
